const WebSocket = require('ws')
const wsController = require('./wsController')
const wsService = require('./wsService')
const SessionRepositiories = require('../repositories/sessionRepositiories')
const jwt = require('jsonwebtoken')
const config = require('../config')
const colors = require('colors') // 命令行颜色化

function createWebSocketServer(server) {
  const wss = new WebSocket.Server({ server })
  global.wss = wss

  // WebSocket 服务器启动时，清空会话记录表
  wss.on('listening', async () => {
    try {
      const deletedCount = await SessionRepositiories.delAllSessions() // 删除所有会话记录
      console.log(colors.green(`✅  会话记录表已清空, 共${deletedCount}条`))
    } catch (error) {
      console.error(colors.red('❌  清空会话记录表失败:'), error)
    }
  })

  // WebSocket 服务器关闭时，通知所有客户端
  wss.on('close', function close() {
    console.log(colors.bgRed('🛑  WebSocket 服务器关闭'))

    // 遍历所有客户端连接，发送关闭指令
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.close(1001, '端点离开，请重新登录') // 发送状态码 1001
      }
    })
  })

  wss.on('connection', async function connection(ws, req) {
    console.log(colors.green('➕  新的客户端连接'))

    // 从 Cookie 中提取 Token
    const cookies = req.headers.cookie
    if (!cookies) {
      ws.close(4001, colors.red('校验失败：客户端未能提供Cookies！'))
      console.log(colors.red('校验失败：客户端未能提供Cookies！ -- 4001'))
      return
    }

    const tokenCookie = cookies.split(';').find(c => c.trim().startsWith('token='))
    if (!tokenCookie) {
      ws.close(4001, colors.red('校验失败：客户端未能提供Token！'))
      console.log(colors.red('校验失败：客户端未能提供Token！ -- 4001'))
      return
    }

    const token = tokenCookie.split('=')[1]

    // 验证 Token
    try {
      const decoded = jwt.verify(token, config.jwtSecret)
      ws.user = decoded // 将用户信息附加到 WebSocket 对象
      console.log(colors.bgCyan('用户已认证:'), colors.magenta(decoded.account))

      // 调用 wsService 处理连接逻辑（创建或更新会话记录）
      await wsService.handleConnection(ws, req)
    } catch (error) {
      console.log(colors.red('Token 校验失败:', error))
      ws.close(4001, 'Token 校验失败')
      return
    }

    // 将 wss 实例绑定到请求对象中，以便在 wsController 和 wsService 中使用
    req.wss = wss

    // 监听消息
    ws.on('message', function incoming(message) {
      console.log(colors.yellow('收到客户端消息:', message.slice(0, 10) + '...'))
      wsController.handleMessage(ws, message, req)
    })

    // 监听连接关闭事件
    ws.on('close', function close() {
      console.log(colors.yellow('🍃  客户端断开连接'))
      // 调用 wsService 处理连接断开逻辑（删除会话记录）
      wsService.handleDisconnect(ws, req)
    })
  })

  console.log(colors.yellow('⭐  WebSocket 服务器已启动!'))
  console.log(colors.yellow('--------------------------------------------------------'))
  console.log()
  return wss
}

module.exports = createWebSocketServer